package com.lry.basic.algorithm.common;

public class Lease<T> {
    //Eureka服务器在接收到实例的最后一次发出的心跳后，需要等待多久才可以将此实例删除，默认为90秒
    public static final int DEFAULT_DURATION_IN_SECS = 90;
    private T holder;//微服务对象
    private long evictionTimestamp;//服务剔除时间戳
    private long registrationTimestamp;//服务注册时间戳
    private long serviceUpTimestamp;//
    private volatile long lastUpdateTimestamp;//最后一次更新的时间，注册下架续约都是更新操作
    private long duration;//duration ms后没有心跳剔除服务
    //private long expireTimestamp;//过期时间
    /**
     * @param r 微服务实例
     * @param durationInSecs Eureka服务器在接收到实例的最后一次发出的心跳后，需要等待多久才可以将此实例删除
     *  eureka.instance.leaseExpirationDurationInSeconds=30s，后一次发出的心跳后，30s后还没有新的心跳剔除服务
     *  eureka.instance.leaseRenewalIntervalInSeconds=10s心跳间隔时间
     */
    public Lease(T r, int durationInSecs) {
        this.holder = r;
        this.registrationTimestamp = System.currentTimeMillis();//注册时间
        this.lastUpdateTimestamp = this.registrationTimestamp;//更新时间=注册时间
        this.duration = (long)(durationInSecs * 1000);//duration ms后没有心跳剔除服务
    }

    //续期操作
    public void renew() {
        this.lastUpdateTimestamp = System.currentTimeMillis() + this.duration;
//        this.lastUpdateTimestamp = System.currentTimeMillis();
//        this.expireTimestamp = System.currentTimeMillis() + this.duration;
    }
    //服务下架/剔除操作
    public void cancel() {
        if (this.evictionTimestamp <= 0L) {
            this.evictionTimestamp = System.currentTimeMillis();
        }
    }

    public void serviceUp() {
        if (this.serviceUpTimestamp == 0L) {
            this.serviceUpTimestamp = System.currentTimeMillis();
        }
    }

    public boolean isExpired() {
        return this.isExpired(0L);
    }

    public boolean isExpired(long additionalLeaseMs) {
        return this.evictionTimestamp > 0L || System.currentTimeMillis() > this.lastUpdateTimestamp + this.duration + additionalLeaseMs;
    }
//    public boolean isExpired(long additionalLeaseMs) {
//        return this.evictionTimestamp > 0L || System.currentTimeMillis() > this.expireTimestamp + additionalLeaseMs;
//    }

    public static void main(String[] args) throws InterruptedException {
        Lease lease = new Lease(new User(1,"lry"),5);
        while(true){
            System.out.println(lease.isExpired());
            Thread.sleep(1000);
        }
    }

    static class User{
        private int id;
        private String name;
        public User(int id,String name){
            this.id = id;
            this.name = name;
        }
    }
}
